Optionally use use xwidgets to display <video> elements in shr
authorLars Ingebrigtsen <larsi@gnus.org>
Tue, 9 Nov 2021 05:19:09 +0000 (06:19 +0100)
committerLars Ingebrigtsen <larsi@gnus.org>
Tue, 9 Nov 2021 05:19:09 +0000 (06:19 +0100)
* doc/misc/eww.texi (Advanced): Document it.
* lisp/net/shr.el (shr-use-xwidgets-for-media): New user option.
(shr-tag-video): Use xwidgets to display <video> elements.

doc/misc/eww.texi
etc/NEWS
lisp/net/shr.el

index 5d308efba4d1f8583b60ad015105f1caf9d49666..95e59d98f8ab5f9b14b0cbdebd7e6c08fd730ce3 100644 (file)
@@ -397,6 +397,15 @@ transformed URL.  By default, this variable contains
 @code{eww-remove-tracking}, which removes the common @samp{utm_}
 trackers from links.
 
+@cindex video
+@vindex shr-use-xwidgets-for-media
+  If Emacs has been built with xwidget support, EWW can use that to
+display @samp{<video>} elements.  However, this support is still
+experimental, and on some systems doesn't work (and even worse) may
+crash your Emacs, so this feature is off by default.  If you wish to
+switch it on, set @code{shr-use-xwidgets-for-media} to a
+non-@code{nil} value.
+
 @node Command Line
 @chapter Command Line Usage
 
index bb25365030deb5c18edf7e8769d27110f6de5055..c9144a5feebc3bf1bb9e4d8c17b63484113795eb 100644 (file)
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -228,7 +228,14 @@ If non-nil, 'C-c C-a' will put attached files at the end of the message.
 *** 'texinfo-mode' now has a specialised 'narrow-to-defun' definition.
 It narrows to the current node.
 
-** eww
+** eww/shr
+
++++
+*** New user option 'shr-use-xwidgets-for-media'.
+If non-nil (and Emacs has been built with support for xwidgets),
+display <video> elements with an xwidget.  Note that this is
+experimental, and is known to crash Emacs on some systems, and just
+doesn't work on other systems.  Also see etc/PROBLEMS.
 
 +++
 *** New user option 'eww-url-transformers'.
index cb8ee73c14c2307080b85341a514377aa073f4e2..295ffddf05938cb76da608cf50a441fd46579d60 100644 (file)
@@ -1626,6 +1626,14 @@ url if no type is specified.  The value should be a float in the range 0.0 to
   :version "24.4"
   :type '(alist :key-type regexp :value-type float))
 
+(defcustom shr-use-xwidgets-for-media nil
+  "If non-nil, use xwidgets to display video and audio elements.
+This also depends on Emacs being built with xwidgets capability.
+Note that this is experimental, and may lead to instability on
+some platforms."
+  :type 'boolean
+  :version "29.1")
+
 (defun shr--get-media-pref (elem)
   "Determine the preference for ELEM.
 The preference is a float determined from `shr-prefer-media-type'."
@@ -1668,10 +1676,36 @@ The preference is a float determined from `shr-prefer-media-type'."
         (start (point)))
     (unless url
       (setq url (car (shr--extract-best-source dom))))
-    (if (> (length image) 0)
-       (shr-indirect-call 'img nil image)
-      (shr-insert " [video] "))
-    (shr-urlify start (shr-expand-url url))))
+    (if (and shr-use-xwidgets-for-media
+             (fboundp 'make-xwidget))
+        ;; Play the video.
+        (progn
+          (let ((widget (make-xwidget
+                         'webkit
+                        "Video"
+                         (truncate (* (window-pixel-width) 0.8))
+                         (truncate (* (window-pixel-width) 0.8 0.75))))
+                (file (make-temp-file "shr" nil ".html")))
+            (run-at-time 1 nil (lambda ()
+                                 (ignore-errors
+                                   (delete-file file))))
+            (insert
+             (propertize
+              " [video] "
+              'display (list 'xwidget :xwidget widget)))
+            (with-temp-buffer
+              (insert
+               (format
+                "<video autoplay loop muted><source src=%S type=\"video/mp4\"></source></video>"
+                url))
+              (write-region (point-min) (point-max) file nil 'silent))
+            (xwidget-webkit-goto-uri widget
+                                     (concat "file://" file))))
+      ;; No xwidgets.
+      (if (> (length image) 0)
+         (shr-indirect-call 'img nil image)
+        (shr-insert " [video] "))
+      (shr-urlify start (shr-expand-url url)))))
 
 (defun shr-tag-audio (dom)
   (let ((url (dom-attr dom 'src))